Completed
Branch master (324e29)
by Michael
07:56 queued 04:16
created

slimbox.js ➔ previous   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
/*!
2
 Slimbox v1.65 - The ultimate lightweight Lightbox clone
3
 (c) 2007-2008 Christophe Beyls <http://www.digitalia.be>
4
 MIT-style license.
5
 */
6
7
var Slimbox;
8
9
(function () {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
10
11
    // Global variables, accessible to Slimbox only
12
    var state = 0, options, images, activeImage, prevImage, nextImage, top, fx, preload, preloadPrev = new Image(), preloadNext = new Image(),
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
13
        // State values: 0 (closed or closing), 1 (open and ready), 2+ (open and busy with animation)
14
15
        // DOM elements
16
        overlay, center, image, prevLink, nextLink, bottomContainer, bottom, caption, number;
17
18
    /*
19
     Initialization
20
     */
21
22
    window.addEvent("domready", function () {
23
        // Append the Slimbox HTML code at the bottom of the document
24
        $(document.body).adopt(
25
            $$([
26
                overlay = new Element("div", {id: "lbOverlay"}).addEvent("click", close),
0 ignored issues
show
Bug introduced by
The variable Element seems to be never declared. If this is a global, consider adding a /** global: Element */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
27
                center = new Element("div", {id: "lbCenter"}),
28
                bottomContainer = new Element("div", {id: "lbBottomContainer"})
29
            ]).setStyle("display", "none")
30
        );
31
32
        image = new Element("div", {id: "lbImage"}).injectInside(center).adopt(
33
            prevLink = new Element("a", {id: "lbPrevLink", href: "#"}).addEvent("click", previous),
34
            nextLink = new Element("a", {id: "lbNextLink", href: "#"}).addEvent("click", next)
35
        );
36
37
        bottom = new Element("div", {id: "lbBottom"}).injectInside(bottomContainer).adopt(
38
            new Element("a", {id: "lbCloseLink", href: "#"}).addEvent("click", close),
39
            caption = new Element("div", {id: "lbCaption"}),
40
            number = new Element("div", {id: "lbNumber"}),
41
            new Element("div", {styles: {clear: "both"}})
42
        );
43
44
        fx = {
45
            overlay: new Fx.Tween(overlay, {property: "opacity", duration: 500}).set(0),
0 ignored issues
show
Bug introduced by
The variable Fx seems to be never declared. If this is a global, consider adding a /** global: Fx */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
46
            image: new Fx.Tween(image, {property: "opacity", duration: 500, onComplete: nextEffect}),
47
            bottom: new Fx.Tween(bottom, {property: "margin-top", duration: 400})
48
        };
49
    });
50
51
52
    /*
53
     API
54
     */
55
56
    Slimbox = {
57
        open: function (_images, startImage, _options) {
58
            options = $extend({
59
                loop: false,                // Allows to navigate between first and last images
60
                overlayOpacity: 0.8,            // 1 is opaque, 0 is completely transparent (change the color in the CSS file)
61
                resizeDuration: 400,            // Duration of each of the box resize animations (in milliseconds)
62
                resizeTransition: false,        // Default transition in mootools
63
                initialWidth: 250,          // Initial width of the box (in pixels)
64
                initialHeight: 250,         // Initial height of the box (in pixels)
65
                animateCaption: true,
66
                showCounter: true,          // If true, a counter will only be shown if there is more than 1 image to display
67
                counterText: "Image {x} of {y}"     // Translate or change as you wish
68
            }, _options || {});
69
70
            // The function is called for a single image, with URL and Title as first two arguments
71
            if (typeof _images == "string") {
72
                _images = [[_images, startImage]];
73
                startImage = 0;
74
            }
75
76
            images = _images;
77
            options.loop = options.loop && (images.length > 1);
78
            position();
79
            setup(true);
80
            top = window.getScrollTop() + (window.getHeight() / 15);
81
            fx.resize = new Fx.Morph(center, $extend({duration: options.resizeDuration, onComplete: nextEffect}, options.resizeTransition ? {transition: options.resizeTransition} : {}));
0 ignored issues
show
Bug introduced by
The variable Fx seems to be never declared. If this is a global, consider adding a /** global: Fx */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
82
            center.setStyles({top: top, width: options.initialWidth, height: options.initialHeight, marginLeft: -(options.initialWidth / 2), display: ""});
83
            fx.overlay.start(options.overlayOpacity);
84
            state = 1;
85
            return changeImage(startImage);
86
        }
87
    };
88
89
    Element.implement({
0 ignored issues
show
Bug introduced by
The variable Element seems to be never declared. If this is a global, consider adding a /** global: Element */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
90
        slimbox: function (_options, linkMapper) {
91
            // The processing of a single element is similar to the processing of a collection with a single element
92
            $$(this).slimbox(_options, linkMapper);
93
94
            return this;
95
        }
96
    });
97
98
    Elements.implement({
0 ignored issues
show
Bug introduced by
The variable Elements seems to be never declared. If this is a global, consider adding a /** global: Elements */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
99
        /*
100
         options:    Optional options object, see Slimbox.open()
101
         linkMapper: Optional function taking a link DOM element and an index as arguments and returning an array containing 2 elements:
102
         the image URL and the image caption (may contain HTML)
103
         linksFilter:    Optional function taking a link DOM element and an index as arguments and returning true if the element is part of
104
         the image collection that will be shown on click, false if not. "this" refers to the element that was clicked.
105
         This function must always return true when the DOM element argument is "this".
106
         */
107
        slimbox: function (_options, linkMapper, linksFilter) {
108
            linkMapper = linkMapper || function (el) {
109
                    return [el.href, el.title];
110
                };
111
112
            linksFilter = linksFilter || function () {
113
                    return true;
114
                };
115
116
            var links = this;
117
118
            links.removeEvents("click").addEvent("click", function () {
119
                // Build the list of images that will be displayed
120
                var filteredLinks = links.filter(linksFilter, this);
121
                return Slimbox.open(filteredLinks.map(linkMapper), filteredLinks.indexOf(this), _options);
122
            });
123
124
            return links;
125
        }
126
    });
127
128
129
    /*
130
     Internal functions
131
     */
132
133
    function position() {
134
        overlay.setStyles({top: window.getScrollTop(), height: window.getHeight()});
135
    }
136
137
    function setup(open) {
138
        ["object", Browser.Engine.trident ? "select" : "embed"].forEach(function (tag) {
0 ignored issues
show
Bug introduced by
The variable Browser seems to be never declared. If this is a global, consider adding a /** global: Browser */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
139
            Array.forEach(document.getElementsByTagName(tag), function (el) {
140
                if (open) el._slimbox = el.style.visibility;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
141
                el.style.visibility = open ? "hidden" : el._slimbox;
142
            });
143
        });
144
145
        overlay.style.display = open ? "" : "none";
146
147
        var fn = open ? "addEvent" : "removeEvent";
148
        window[fn]("scroll", position)[fn]("resize", position);
149
        document[fn]("keydown", keyDown);
150
    }
151
152
    function keyDown(event) {
153
        switch (event.code) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
154
            case 27:    // Esc
155
            case 88:    // 'x'
156
            case 67:    // 'c'
157
                close();
158
                break;
159
            case 37:    // Left arrow
160
            case 80:    // 'p'
161
                previous();
162
                break;
163
            case 39:    // Right arrow
164
            case 78:    // 'n'
165
                next();
166
        }
167
        // Prevent default keyboard action (like navigating inside the page)
168
        return false;
169
    }
170
171
    function previous() {
172
        return changeImage(prevImage);
173
    }
174
175
    function next() {
176
        return changeImage(nextImage);
177
    }
178
179
    function changeImage(imageIndex) {
180
        if ((state == 1) && (imageIndex >= 0)) {
181
            state = 2;
182
            activeImage = imageIndex;
183
            prevImage = ((activeImage || !options.loop) ? activeImage : images.length) - 1;
184
            nextImage = activeImage + 1;
185
            if (nextImage == images.length) nextImage = options.loop ? 0 : -1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
186
187
            $$(prevLink, nextLink, image, bottomContainer).setStyle("display", "none");
188
            fx.bottom.cancel().set(0);
189
            fx.image.set(0);
190
            center.className = "lbLoading";
191
192
            preload = new Image();
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
193
            preload.onload = nextEffect;
194
            preload.src = images[imageIndex][0];
195
        }
196
197
        return false;
198
    }
199
200
    function nextEffect() {
201
        switch (state++) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
202
            case 2:
203
                center.className = "";
204
                image.setStyles({backgroundImage: "url(" + images[activeImage][0] + ")", display: ""});
205
                $$(image, bottom).setStyle("width", preload.width);
206
                $$(image, prevLink, nextLink).setStyle("height", preload.height);
207
208
                caption.set('html', images[activeImage][1] || "");
209
                number.set('html', (options.showCounter && (images.length > 1)) ? options.counterText.replace(/{x}/, activeImage + 1).replace(/{y}/, images.length) : "");
210
211
                if (prevImage >= 0) preloadPrev.src = images[prevImage][0];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
212
                if (nextImage >= 0) preloadNext.src = images[nextImage][0];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
213
214
                if (center.clientHeight != image.offsetHeight) {
215
                    fx.resize.start({height: image.offsetHeight});
216
                    break;
217
                }
218
                state++;
219
            case 3:
220
                if (center.clientWidth != image.offsetWidth) {
221
                    fx.resize.start({width: image.offsetWidth, marginLeft: -image.offsetWidth / 2});
222
                    break;
223
                }
224
                state++;
225
            case 4:
226
                bottomContainer.setStyles({top: top + center.clientHeight, marginLeft: center.style.marginLeft, visibility: "hidden", display: ""});
227
                fx.image.start(1);
228
                break;
229
            case 5:
230
                if (prevImage >= 0) prevLink.style.display = "";
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
231
                if (nextImage >= 0) nextLink.style.display = "";
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
232
                if (options.animateCaption) {
233
                    fx.bottom.set(-bottom.offsetHeight).start(0);
234
                }
235
                bottomContainer.style.visibility = "";
236
                state = 1;
237
        }
238
    }
239
240
    function close() {
241
        if (state) {
242
            state = 0;
243
            preload.onload = $empty;
0 ignored issues
show
Bug introduced by
The variable $empty seems to be never declared. If this is a global, consider adding a /** global: $empty */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
244
            for (var f in fx) fx[f].cancel();
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
245
            $$(center, bottomContainer).setStyle("display", "none");
246
            fx.overlay.chain(setup).start(0);
247
        }
248
249
        return false;
250
    }
251
252
})();
253